package com.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.domain.ResponseResult;
import com.example.domain.entity.News;
import com.example.mapper.NewsMapper;
import com.example.mapper.StarMapper;
import com.example.service.NewsService;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.*;

@Service
public class NewsServiceImpl implements NewsService {
    @Autowired
    private NewsMapper newsMapper;
    @Autowired
    private StarMapper starMapper;
    @Autowired(required = false)
    private Configuration hadoopConfig;

    @Override
    public List<News> recommendMaxClick() {
        List<News> result = new ArrayList<>();
        List<News> news = newsMapper.recommendMaxClick();

        if (news == null) {
            throw new RuntimeException("新闻不存在");
        }
        //只取点击数前十的新闻
        int j=0;
        for (int i = 0; i < news.size(); i++) {
            News news1=news.get(i);
            if(news1.getText()==null||news1.getText().equals("")) continue;
            if(news1.getTitle()==null||news1.getTitle().equals("")) continue;
            result.add(news.get(i));
            j++;
            if (j >= 10) return result;
        }
        return result;

    }

    @Override
    public List<News> recommendByTags(String tag) {
        List<News> result = new ArrayList<>();
        List<News> news = newsMapper.recommendByTag(tag);

        Random random = new Random();
        if (news == null) {
            throw new RuntimeException("不存在符合标签的新闻");
        }
        HashSet set = new HashSet<>();
        if (news.size() > 5) {
            while (true) {
                int i=random.nextInt(news.size());
                News news1=news.get(i);
                if(news1.getText()==null||news1.getText().equals("")) continue;
                if(news1.getTitle()==null||news1.getTitle().equals("")) continue;
                set.add(news.get(i));
                if (set.size() == 5) break;
            }
        } else {
            while (true) {
                int i=random.nextInt(news.size());
                News news1=news.get(i);
                if(news1.getText()==null||news1.getText().equals("")) continue;
                if(news1.getTitle()==null||news1.getTitle().equals("")) continue;
                set.add(news.get(i));
                if (set.size() == news.size()) break;
            }
        }
        result.addAll(set);
        return result;
    }

    @Override
    public List<News> recommendByClickPercent() {
        List<News> result=new ArrayList<>();
        List<News> news = newsMapper.recommendBylikePercent();
        int j=0;
        for (int i = 0; i < news.size(); i++) {
            News news1=news.get(i);
            if(news1.getText()==null||news1.getText().equals("")) continue;
            if(news1.getTitle()==null||news1.getTitle().equals("")) continue;
            result.add(news.get(i));
            j++;
            if (j >= 10) return result;

        }
        return result;
    }

    @Override
    public int[] recommendByAll(String tag) {

        Random random=new Random();
        int[] news = newsMapper.recommendByAll(tag);
        HashSet<Integer> set=new HashSet<Integer>();
        for (int i=0;i<news.length;i++){
            set.add(news[random.nextInt(1000)]);
            if (set.size()>30){
                break;
            }
        }
        int []result=new int[set.size()];
        Object[] ss=set.toArray();
        for(int i=0;i< ss.length;i++){
            result[i]=(int)ss[i];
        }


        return result;
    }

    @Override
    public List<News> findById(int[] a) {
        List<News> result=new ArrayList<>();
        for (int j : a) {
            News news = newsMapper.findById(j);
            if (!Objects.equals(news.getTitle(), "") && !Objects.equals(news.getText(), "")) {
                result.add(newsMapper.findById(j));
            }
        }
        return  result;
    }



    @Override
    public ResponseResult selectByTag() {
        try {
            importDataFromHadoopToMySQL("hdfs://43.142.41.87:24655/user/hadoop/data.csv");
        } catch (Exception e) {
            e.printStackTrace();
        }
        QueryWrapper<News> wrapper = new QueryWrapper<News>()
                .select("newsTag,count(*) as tag_count")
                .groupBy("newsTag");

        List<Map<String,Object>> list = newsMapper.selectMaps(wrapper);
        if(Objects.isNull(list)){
            throw new RuntimeException("数据为空");
        }
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult selectByLike() {
        try {
            importDataFromHadoopToMySQL("hdfs://43.142.41.87:24655/user/hadoop/data.csv");
        } catch (Exception e) {
            e.printStackTrace();
        }
        QueryWrapper<News> wrapper = new QueryWrapper<News>()
                .select("newsTag,ROUND(AVG(IFNULL(praise, 0) / IFNULL(click, 1)), 4)  as like_avg")
                .groupBy("newsTag");

        List<Map<String,Object>> list = newsMapper.selectMaps(wrapper);
        if(Objects.isNull(list)){
            throw new RuntimeException("数据为空");
        }
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult selectByClick() {
        try {
            importDataFromHadoopToMySQL("hdfs://43.142.41.87:24655/user/hadoop/data.csv");
        } catch (Exception e) {
            e.printStackTrace();
        }
        QueryWrapper<News> wrapper = new QueryWrapper<News>()
                .select("newsTag,round(avg(click),4) as click_avg")
                .groupBy("newsTag");

        List<Map<String,Object>> list = newsMapper.selectMaps(wrapper);
        if(Objects.isNull(list)){
            throw new RuntimeException("数据为空");
        }
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult selectByFinishPercent() {
        try {
            importDataFromHadoopToMySQL("hdfs://43.142.41.87:24655/user/hadoop/data.csv");
        } catch (Exception e) {
            e.printStackTrace();
        }
        QueryWrapper<News> wrapper = new QueryWrapper<News>()
                .select("newsTag,round(avg(finishPercent),4) as finish_avg")
                .groupBy("newsTag");

        List<Map<String,Object>> list = newsMapper.selectMaps(wrapper);
        if(Objects.isNull(list)){
            throw new RuntimeException("数据为空");
        }
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult selectAll() {
        try {
            importDataFromHadoopToMySQL("hdfs://43.142.41.87:24655/user/hadoop/data.csv");
        } catch (Exception e) {
            e.printStackTrace();
        }
        List<Map<String,Object>> list = newsMapper.selectAll();
        List<Map<String,Object>> list1 = starMapper.selectByStar();
        List<Map<String,Object>> list2=new LinkedList<>();

        for(int i=0;i<list.size();i++){

            Map<String, Object> combineResultMap = new HashMap<String, Object>();
            combineResultMap.putAll(list.get(i));
            combineResultMap.putAll(list1.get(i));
            list2.add(combineResultMap);
        }
        if(Objects.isNull(list2))
            throw new RuntimeException("数据为空");

        return ResponseResult.okResult(list2);
    }



    public void importDataFromHadoopToMySQL(String hadoopFilePath) throws Exception {
        FileSystem fileSystem = FileSystem.get(hadoopConfig);
        Path path = new Path(hadoopFilePath);
        if (!fileSystem.exists(path)) {
            throw new Exception("File not exists: " + hadoopFilePath);
        }
        BufferedReader br = new BufferedReader(new InputStreamReader(fileSystem.open(path)));
        String line;
        while ((line = br.readLine()) != null) {
            String[] fields = line.split(",");
            News data = new News();
            data.setId(Integer.parseInt(fields[0]));
            data.setNewsTag(String.valueOf(Integer.parseInt(fields[1])));
            data.setTitle(fields[2]);
            data.setText(fields[3]);
            data.setClick(Integer.parseInt(fields[4]));
            data.setFinishPercent(Double.parseDouble(fields[5]));
            data.setPraise(Integer.parseInt(fields[6]));
            data.setUnlike(Integer.parseInt(fields[7]));
            newsMapper.insert(data);
        }
        br.close();
    }
}